package com.lhcai.haweiOD;

/**
 * @author lhcstart
 * @create 2023-02-27 17:35
 */


import java.util.*;

/**
 * 扑克牌问题
 * <p>
 * 步骤一：
 * 对扑克牌进行分组，规则如下
 * 当牌面数字相同张数大于等于4时，组合牌为炸弹；
 * 三张相同牌面数字+两张相同牌面数字，且三张牌与两张牌不相同时，组合牌为葫芦；
 * 三张相同牌面数字，组合牌为三张，
 * 两张相同牌面数字，组合牌为对子，
 * 剩余没有相同的牌则为单张
 * <p>
 * 步骤二：
 * 对上述组合牌进行由大到小排列，规则如下：
 * 不同类型组合牌之间由大到小排列规则：
 * 炸弹 > 葫芦 > 三张 > 对子 > 单张
 * 相同类型组合牌之间，除葫芦外，按组合牌全部牌面数字加总，由大到小排列
 * 葫芦则先按三张相同牌面数字加总，由大到小排列，三张相同牌面数字加总相同时，再按另外两张牌面数字加总，由大到小排列；
 * 由于葫芦大于三张，因此如果能形成更大的组合牌，也可以将三张拆分为两张或一张，其中的两张可以和其他三张重新组合成葫芦，剩下的一张为单张；
 * <p>
 * 步骤三：
 * 当存在多个可能组合方案时，按如下规则排序取最大的一个组合牌：
 * 依次对组合方案中的组合牌进行大小比较，规则同上；
 * 当组合方案A中的第N个组合牌 > 组合方案B中的第N个组合牌时，即组合方案A大于组合方案B；
 */
public class HJ198 {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String s = sc.nextLine();
            solve(s);
        }
    }

    public static void solve(String s) {

        String[] split = s.split("");
        //存放进map里，key为数字，value为出现的次数
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < split.length; i++) {
            int num = Integer.parseInt(split[i]);
            map.put(num, map.getOrDefault(num, 0) + 1);
        }
        //自定义排序规则
        Comparator<Map.Entry<Integer, Integer>> entryComparator = (a, b) -> {
            if (!a.getValue().equals(b.getValue())) {
                return b.getValue() - a.getValue();//次数不等，根据次数降序
            } else {
                return b.getKey() - a.getValue();//次数相等，根据大小降序
            }
        };
        //创建list存放键值对
        List<Map.Entry<Integer, Integer>> list = new ArrayList<>(map.entrySet());
        StringBuilder sb = new StringBuilder();
        //循环开始处理数据
        while (list.size() > 0) {

            list.sort(entryComparator);//根据自定义的排序规则排序

            Map.Entry<Integer, Integer> first = list.get(0);

            //炸弹
            if (first.getValue() >= 4) {
                append(sb, first.getKey(), 4);
                if (first.getValue() - 4 == 0) {
                    list.remove(0);
                } else {
                    first.setValue(first.getValue() - 4);
                }
                continue;
            }
            //葫芦或三
            if (first.getValue() == 3 && list.size() > 1) {//list.size() > 1代表后面还有牌，不是单纯的三张
                Map.Entry<Integer, Integer> second = list.get(1);
                if (second.getValue() >= 2) {
                    append(sb, first.getKey(), 3);
                    append(sb, second.getKey(), 2);
                    if (second.getValue() == 2) {
                        list.remove(1);
                    } else {
                        second.setValue(second.getValue() - 2);
                    }
                    list.remove(0);
                    continue;
                } else {
                    append(sb, first.getKey(), 3);
                    list.remove(0);
                    continue;
                }
            }
            //其他
            int size = list.size();
            for (int i = 0; i < size; i++) {
                append(sb, list.get(0).getKey(), list.get(0).getValue());
                list.remove(0);
            }
        }
        System.out.println(sb.substring(0, sb.length() - 1));//去除末尾空格
    }

    //自定义添加规则
    //number  数字  count 次数
    public static void append(StringBuilder sb, int number, int count) {
        for (int i = 0; i < count; i++) {
            sb.append(number).append(" ");
        }
    }

}


